算法——蛮力法之顺序查找和蛮力字符串匹配
接着昨天的选择排序和冒泡排序之后,今天来实现一下顺序查找和蛮力字符串匹配两个算法。
顺序查找就是将给定的查找键和列表周玲的每个元素进行比较,直到找到一个匹配成功的元素返回该元素下标,查找成功,或者查找整个列表二没有匹配元素,查找失败。这里记录一下限位器版顺序查找方法。限位器就是指将查找键添加到列表最后,这样在查找的过程中,不用再每次都判断是否到达列表尾部来判断查找是否失败,而是在查找结束后,判断匹配元素下标是否小于n(假设列表有n个元素)来判断查找是否成功。下面是限位器版顺序查找算法:
限位器版顺序查找算法: SequentialSearch(A[0....n], K) //输入:一个n个元素的数组A和一个查找键K //输出:第一个值等于K的元素的位置,如果找不到这样的元素,返回-1 A[n]<—K while A[i]≠K do i++ if i<n return i; else return -1; //这个算法是《算法设计与分析》上的,我认为这里的else没有必要,当查找成功时已经提前返回主函数, //不会再执行return -1,在代码实现的过程中,尝试了去掉else,运行结果也是正确的 |
上面这种算法的时间复杂度是:Θ(n)
下面是该算法的C++实现代码:
#include <iostream> using namespace std; typedef char Elemtype; int SequentialSearch(Elemtype ESearch[], int n, Elemtype K); void main(){ Elemtype a[6] = {'a','r','j','l','h'};//定义的数组长度要比原表大1,预留出K的位置 Elemtype K; cin >> K; getchar(); int iLocation = SequentialSearch(a, 5, K);//这里传递的是列表下标的最大值 if (iLocation == -1){ cout << "查找失败,列表中没有"<<K<<"元素"; } else cout << "查找成功,该元素位置为:" << iLocation; getchar(); } int SequentialSearch(Elemtype ESearch[], int n,Elemtype K){ ESearch[n] = K; int i = 0; while (ESearch[i] != K){ i++; } if (i < n){ return i; } return -1; }
下面介绍一下蛮力字符串匹配。
该算法的做法是将模式(也就是较短的子串,长度为m)对准文本(也就是较长的字符串,长度为n)的前m个字符,从左到右匹配每一对相应的字符,如果有m对字符都匹配成功,那么算法停止,或者当遇到有一对不匹配时就将模式向右移一位,然后继续从模式的第一个字符与文本进行匹配。在这个过程中,当文本剩余字符的长度小于模式时算法就可以停止了,因为后面的都不可能再匹配成功,因此,文本的下标达到n-m时终止。下面是蛮力字符串匹配的算法:
蛮力匹配字符串算法: BruteForceStringMatch(T[0....n-1],P[0...m-1]) //输入:一个n个字符的数组T[0...n-1]代表一段文本,一个m个字符的数组P[0...m-1]代表一个模式 //输出:匹配成功时返回文本中第一个匹配子串的第一个字符的位置,失败时返回-1 for i<—0 to n-m do j <—0 while T[i+j] = P[j] and j < m do j++ if j=m return i return -1 |
该算法的时间复杂度在最坏的情况下也就是每次模式匹配都进行到最后一对字符时匹配失败,也就是要进行m次比较,这样就要进行n-m+1次这样的匹配,该算法属于Θ(nm),书上描述的在查找随机文本时,显示出的是线性效率Θ(n+m)=Θ(n)。下面是该算法的C++实现代码:
#include <iostream> using namespace std; typedef char Elemtype; int BruteForceStringMatch(Elemtype T[], int n, Elemtype P[], int m); int main(){ Elemtype T[10] = { 'a', 'p', 'p', 'l', 'e', 's' }; Elemtype P[3] = { 'p', 'p','l' }; Elemtype Ps[2] = { 'p', 's' }; int result1 = BruteForceStringMatch(T, 10, P, 3); if (result1 == -1){ cout << "T和P的匹配失败"; } else cout << "T和P匹配成功,P在T中的字符起始位置为:" << result1; getchar(); return 1; } int BruteForceStringMatch(Elemtype T[], int n, Elemtype P[], int m){ int i = 0,j=0; for (i = 0; i < n - m; i++){ j = 0; while (j < m && T[i + j] == P[j]){ j++; } if (j == m){ return i; } } return -1; }